package org.jeecg.modules.meter.web;

import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.ForeignResult;
import org.jeecg.common.api.vo.MeterForeignResult;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.RedisKeyConstant;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.MD5Utils;
import org.jeecg.common.util.StringUtils;
import org.jeecg.entity.charge.ChargeFeeRule;
import org.jeecg.entity.meter.MeterHandRead;
import org.jeecg.entity.meter.MeterRead;
import org.jeecg.lock.client.RedissonLockClient;
import org.jeecg.common.util.DateUtil;
import org.jeecg.modules.meter.iot.entity.MeterCollectInfoDto;
import org.jeecg.modules.meter.service.IMeterHandReadService;
import org.jeecg.modules.meter.service.IMeterReadService;
import org.jeecg.modules.meter.service.impl.ForeignMeterCallBackServiceImpl;
import org.jeecg.vo.meter.ForeignMeterCallBackReq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Api(tags="测试对外接口")
@RestController
@RequestMapping("b/meter/foreign/iot")
public class ForeignMeterIoTController {

    @Autowired
    private ForeignMeterCallBackServiceImpl foreignMeterCallBackService;

    @Autowired
    private IMeterReadService meterReadService;

    @Autowired
    private RedissonLockClient lockClient;

    @Autowired
    private IMeterHandReadService meterHandReadService;

    private final static String appKey = "yktcxyunnetcn";

    @AutoLog(value = "添加仪表基础信息")
    @ApiOperation(value="添加仪表基础信息", notes="添加仪表基础信息")
    @PostMapping(value = "/saveMeterBase")
    public MeterForeignResult saveMeterBase(@RequestBody String json,HttpServletRequest req){
        JSONObject jsonObject = JSONObject.parseObject(json);
        String meterCode = jsonObject.getString("meterCode");
        String meterKey = jsonObject.getString("meterKey");
        MeterCollectInfoDto collectInfoDto = new MeterCollectInfoDto();
        if (StringUtils.isNotBlank(meterKey)){
            collectInfoDto.setMeterKey(meterKey);
        }else {
            collectInfoDto.setMeterKey(meterCode);
        }
        return MeterForeignResult.ok(collectInfoDto);
    }


    @AutoLog(value = "模拟硬件读表")
    @ApiOperation(value="模拟硬件读表", notes="模拟硬件读表")
    @PostMapping(value = "/collectInfo")
    public MeterForeignResult collectInfo(@RequestBody String json , HttpServletRequest req) {
        JSONObject jsonObject = JSONObject.parseObject(json);
        String meterCode = jsonObject.getString("meterKey");
        MeterRead meterRead = meterReadService.getLastMeterReadByNo(meterCode);
        List<MeterCollectInfoDto> meterReadList = new ArrayList<>();
        if (meterRead != null){
            MeterCollectInfoDto collectInfoDto = new MeterCollectInfoDto();
            collectInfoDto.setMeterKey(meterCode);
            collectInfoDto.setReadTime(DateUtils.date2Str(new Date(),DateUtils.datetimeFormat));
            BigDecimal nowRead = meterRead.getNowRead() == null ? BigDecimal.ZERO:new BigDecimal(meterRead.getNowRead());
            nowRead = nowRead.add(new BigDecimal(57.62));
            collectInfoDto.setTotalUse(nowRead.toString());
            meterReadList.add(collectInfoDto);
        } else {
            MeterCollectInfoDto collectInfoDto = new MeterCollectInfoDto();
            collectInfoDto.setMeterKey(meterCode);
            collectInfoDto.setReadTime(DateUtils.date2Str(new Date(),DateUtils.datetimeFormat));
            collectInfoDto.setTotalUse("1");
            meterReadList.add(collectInfoDto);
        }
        return MeterForeignResult.ok(meterReadList);
    }

    @AutoLog(value = "测试分布式锁")
    @ApiOperation(value="测试分布式锁", notes="测试分布式锁")
    @PostMapping(value = "/testLock")
    public Result testLock(String lockKey){
        String key = RedisKeyConstant.METER_ORDER_KEY + lockKey;
        boolean getLock = lockClient.tryLock(key,0,20);
        if (getLock){
            //释放锁
//            lockClient.unlock(key);
            return Result.ok("成功");
        }else {
            return Result.error("失败");
        }

    }



    /**
     * 接收 - 电表硬件平台回调接口
     * @return
     */
    @PostMapping(value = "/serviceCallback")
    public MeterForeignResult serviceCallback(@RequestBody ForeignMeterCallBackReq callBackReq){
        try{
            log.info("电表硬件回调接到的数据serviceCallback:{}",callBackReq);
            if (StringUtils.isBlank(callBackReq.getAppKey())){
                return MeterForeignResult.error("appKey不可为空");
            }
            //校验appKey
            if (!MD5Utils.getMd5(appKey).toLowerCase().equals(MD5Utils.getMd5(callBackReq.getAppKey()).toLowerCase())){
                return MeterForeignResult.error("appKey参数不对！");
            }
            ForeignResult result = foreignMeterCallBackService.serviceCallback(callBackReq);
        }catch (Exception e){
            log.error("电表记录推送处理异常:{}",e);
            return MeterForeignResult.error("处理异常");
        }
        return MeterForeignResult.ok();
    }


         /*--------------------------------手抄表APP---------------------------------------------*/


    @RequestMapping("handMeter")
    public Result<?> handMeter (@RequestParam("roomId")String roomId,
                                @RequestParam("feeId")String feeId,
                                @RequestParam("readMonth")String readMonth,
                                @RequestParam("nowUse")String nowUse) throws ParseException {
       SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
       DateUtil dateUtil = DateUtil.builder().build();
       ChargeFeeRule chargeStandard = meterHandReadService.queryChargeRule(feeId, roomId);
       if (null == chargeStandard){
           return Result.error("该房间未配置该收费项,请确认");
       }
       if (StringUtils.isEmpty(readMonth)){
           return  Result.error("请选择抄表月份");
       }
       if (StringUtils.isEmpty(nowUse)) {
           return Result.error("请输入读数");
       }
       //精度
       Integer unitAccount = chargeStandard.getUnitAccount();
       if(null == unitAccount){
           unitAccount = 2;
       }
       //四舍五入法
       Integer roundMode = chargeStandard.getRoundMode();
       BigDecimal price =  chargeStandard.getPrice();
       BigDecimal nowRead = new BigDecimal(nowUse);
       MeterHandRead  newMeterHand = new MeterHandRead();
       newMeterHand.setNewRead(nowUse);
       newMeterHand.setPrice(price);
       newMeterHand.setRoomId(roomId);
       newMeterHand.setProjectId(chargeStandard.getProjectId());
       newMeterHand.setBillsStatus(0);
       newMeterHand.setFeeId(feeId);
       //获取最后一次抄表月份
       MeterHandRead meterHandRead = meterHandReadService.queryChargeLastRead(feeId,roomId);
       if ( null == meterHandRead){
           BigDecimal amount = nowRead.multiply(price).setScale(unitAccount,roundMode);
           newMeterHand.setAmount(amount);
           newMeterHand.setPreRead("0");
           newMeterHand.setUsed(new BigDecimal(nowUse));
           newMeterHand.setReadMonth(readMonth);
           newMeterHand.setCoverStartDate(dateFormat.parse(dateUtil.getMinMonthDate(readMonth)));
           newMeterHand.setCoverEndDate(dateFormat.parse(dateUtil.getMaxMonthDate(readMonth)));
           newMeterHand.setCoverDate(readMonth+"~"+readMonth);
       }else {
           //第二次抄表 获取计量月是否小于抄表月  读数大小
           String newRead = meterHandRead.getNewRead();
           if (nowUse.compareTo(newRead) < 0) {
               return Result.error("当前读数小于上一次读数");
           }
           String oldReadMonth = meterHandRead.getReadMonth();
           int i = oldReadMonth.compareTo(readMonth);
           if (i >= 0) {
               return Result.error("当前月份已经抄表");
           }
           //判断是否是跨月账单
           int count = dateUtil.compareToInt(oldReadMonth, readMonth);
           if (count > 1) {
               //跨月账单 则起始账单为抄表月份下一个月开始
               String startMonth = dateUtil.addMonth(oldReadMonth);
               String minMonthDate = dateUtil.getMinMonthDate(startMonth);
               String endMonthDate = dateUtil.getMaxMonthDate(readMonth);
               newMeterHand.setReadMonth(readMonth);
               newMeterHand.setCoverStartDate(dateFormat.parse(minMonthDate));
               newMeterHand.setCoverEndDate(dateFormat.parse(endMonthDate));
               newMeterHand.setCoverDate(startMonth + "~" + readMonth);
           } else {
               newMeterHand.setReadMonth(readMonth);
               newMeterHand.setCoverStartDate(dateFormat.parse(dateUtil.getMinMonthDate(readMonth)));
               newMeterHand.setCoverEndDate(dateFormat.parse(dateUtil.getMaxMonthDate(readMonth)));
               newMeterHand.setCoverDate(readMonth + "~" + readMonth);
           }
       }
       try {
           meterHandReadService.save(newMeterHand);
           return Result.ok("抄表成功");
       }catch (Exception e){
           e.printStackTrace();
           return Result.error("抄表失败,系统繁忙");
       }
   }
}
